package com.aaa.config;

import cn.hutool.json.JSONUtil;
import com.aaa.entity.Result;
import com.aaa.until.JWTUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;


import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: springsecurity04
 * @description:
 * @author: 闫克起2
 * @create: 2022-11-01 15:11
 **/
@Configuration
public class MySpringSecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    //定义表单规则以及过滤规则
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        //表单的规则
        http.formLogin()
                .loginPage("/login.html")
                //该路径没有对应的控制层 交于springsecurity完成登录功能
                .loginProcessingUrl("/login")
                //.successForwardUrl("/success")
                .successHandler(successHandler())
                .permitAll();
        //禁用跨域伪造
        http.csrf().disable();

        //其他请求必须认证后才能访问
        http.authorizeRequests().anyRequest().authenticated();

        return http.build();

    }
    private AuthenticationSuccessHandler successHandler(){
        return (request, response, authentication) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();

            //生成token 按照用户名和用户具有的权限。
            Map<String,Object> map=new HashMap<>();
            User principal = (User) authentication.getPrincipal();
            //获取当前用户的名称
            String username = principal.getUsername();
            //获取当前用户具有的权限
            Collection<GrantedAuthority> authorities = principal.getAuthorities();

            //stream流把集合中原生的类型转化为另一张类型
            List<String> list = authorities.stream().map(item -> item.getAuthority()).collect(Collectors.toList());
            map.put("username",username);
            map.put("authorities",list);
            String token = JWTUtil.createJWT(map);

            //封装到公共json对象中
            Result result=new Result(200,"登录成功",token);
            String json = JSONUtil.toJsonStr(result);
            writer.print(json);

            writer.flush();
            writer.close();

        };
    }
}